package persistence;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import bank.AbstractModel;
import bank.Kunden;


public class PersistenceManager {

    private static final String PERSISTANCE_FILE_NAME = "kunden.ser";
    
    public static final String PROPERTYNAME_DATA_CHANGED = "dataChanged";

    private static PersistenceManager instance;
    
    private final PropertyChangeListener persistanceHandler;
    private final PropertyChangeSupport changeSupport;

    private Kunden kunden;


    private PersistenceManager() {
        persistanceHandler = new PersistanceHandler();
        changeSupport = new PropertyChangeSupport(this);
    }

    public static PersistenceManager getInstance() {
        if (instance == null) {
            createInstance();
        }
        return instance;
    }

    private static void createInstance() {
        instance = new PersistenceManager();
    }

    public Kunden getKunden() {
        if (kunden == null) {
            kunden = loadKunden();
        }
        return kunden;
    }

    private Kunden loadKunden() {
        ObjectInputStream input = null;
        try {
            input = new ObjectInputStream(new FileInputStream(PERSISTANCE_FILE_NAME));
            return (Kunden) input.readObject();
        } catch (Exception e) {
            // Ignorieren...
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return new Kunden();
    }

    public void registerModel(AbstractModel aModel) {
        aModel.addPropertyChangeListener(persistanceHandler);
    }
    
    public void addPropertyChangeListener(String aPropertyName, PropertyChangeListener aListener) {
    	changeSupport.addPropertyChangeListener(aPropertyName, aListener);
    }


    // Inner Classes ***********************************************************

    private class PersistanceHandler implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            ObjectOutputStream output = null;
            try {
                output = new ObjectOutputStream(new FileOutputStream(PERSISTANCE_FILE_NAME));
                output.writeObject(getKunden());
            } catch (Exception e) {
                throw new IllegalStateException("Anwendung konnte nicht persitiert werden! Fehlerursache: "
                                              + e.getLocalizedMessage(), e);
            } finally {
                if (output != null) {
                    try {
                        output.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            changeSupport.firePropertyChange(PROPERTYNAME_DATA_CHANGED, null, kunden);
        }
    }
}
